#include "mitsubishiwnd.h"
//#include "Modbus/ModbusRTU/version.h"
#include "common.h"
#include <QHeaderView>//

MitsubishiWnd::MitsubishiWnd(QString port,QString baud,QString dataBits,QString parity,QString stopBits,QWidget *parent) :
    QWidget(parent),
    m_modelTxPktQueue(new QStandardItemModel(this) ),
    m_modelTxRxResult(new QStandardItemModel(this) ),
    m_threadForSerial(new QThread(this) ),
    m_timerAutoSend(new QTimer(this))
{
    m_timerAutoSend->setSingleShot(true);
    m_parsedSysData.clear();
    m_receiveData.clear();
    m_parsedWarnData.clear();
    m_ammeterData.clear();
    m_warnValue = 0;
    m_WgtChanged = PLASTIC_MAIN_WGT;
    QStringList headers;
    headers << "ENABLE" << "HEX" << "ASCII" << "COMMENT";
    m_modelTxPktQueue->setHorizontalHeaderLabels(headers);
    m_viewTxQueueData =  new QTableView(this);
    m_viewTxQueueData->setModel(m_modelTxPktQueue);
    m_viewTxQueueData->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    m_viewTxQueueData->setSelectionMode(QAbstractItemView::QAbstractItemView::SingleSelection);
    m_viewTxQueueData->setSelectionBehavior(QAbstractItemView::SelectRows);
    headers.clear();
    headers << "TIME STAMP" << "STATUS" << "MODE" << "RAW DATA" <<  "CRC" << "S ADDR" << "FUNC" << "INFO";
    m_modelTxRxResult->setHorizontalHeaderLabels(headers);
    m_viewTxRxResult = new QTableView(this);
    m_viewTxRxResult->setModel(m_modelTxRxResult);
    m_viewTxRxResult->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_viewTxRxResult->horizontalHeader()->setStretchLastSection(true);
    m_viewTxRxResult->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    m_viewTxRxResult->setSelectionMode(QAbstractItemView::QAbstractItemView::SingleSelection);
    m_viewTxRxResult->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_rxCount = 0;
    m_txCount = 0;
    m_errorCount = 0;
    m_txRxResultMaxRow = 20000;
    m_position = -1;    
    mComPortSetting.cmbComPort = port;
    mComPortSetting.cmbBaudrate = baud;
    mComPortSetting.cmbDataBits = dataBits;
    mComPortSetting.cmbParity  = parity;
    mComPortSetting.cmbStopBits = stopBits;
    createConnection();
    onSendCmd("02","30","1000","0E","03","ASCII");//读工作参数
    onSendCmd("02","30","117C","04","03","ASCII");//读取工件计数值
}

MitsubishiWnd::~MitsubishiWnd()
{
    m_threadForSerial->exit();
    if (m_port) {
        delete m_port;
    }
    if (m_viewTxQueueData) {
        delete m_viewTxQueueData;
    }
    if (m_viewTxRxResult) {
        delete m_viewTxRxResult;
    }
}

void MitsubishiWnd::createConnection()
{
    m_port = new SerialPort();
    m_port->setMode("ASCII");
    // for serial
    connect(m_port,                     SIGNAL(sgReceivedData(QByteArray)),     this,               SLOT(onRecvedData(QByteArray) ));
    connect(m_port,                     SIGNAL(sgReceivedErrorData(QByteArray)),this,               SLOT(onRecvedErrorData(QByteArray) ));
    connect(m_port,                     SIGNAL(sgSendedData(QByteArray)),       this,               SLOT(onSendedData(QByteArray)   ));
    connect(m_threadForSerial,          SIGNAL(finished()),                     m_port,             SLOT(deleteLater())                 );
    connect(m_threadForSerial,          SIGNAL(started()),                      m_port,             SLOT(init())                 );
    connect(m_port,                     SIGNAL(sgConnected()),                  this,               SLOT(onPortConnected()                        ));
    connect(m_port,                     SIGNAL(sgDisconnected()),               this,               SLOT(onPortDisconnected()                     ));
    connect(m_port,                     SIGNAL(sgResponseTimeout()),            this,               SLOT(onPortResponseTimeout()                  ));

    //时机很重要，所以要提高优先顺序
    m_port->moveToThread(m_threadForSerial);
    m_threadForSerial->start(QThread::TimeCriticalPriority);
    onSetPortTimeOut();//设置串口超时时间
    connect(this,                       SIGNAL(toggleAutoSend(bool)),              this, SLOT(onChkAutoSendToggled(bool)               ));
    connect(this,                       SIGNAL(sgErrorCountChanged()),              this, SLOT(onErrorCountChanged()                       ));
    connect(this,                       SIGNAL(sendWriteList(QStringList)),         this, SLOT(onReceiveWriteList(QStringList) ));
    connect(m_modelTxPktQueue,          SIGNAL(dataChanged(QModelIndex,QModelIndex)),
            this, SLOT(onModelTxPktQueueDataChanged(QModelIndex, QModelIndex) ));
    connect(m_timerAutoSend,            SIGNAL(timeout()),                      this, SLOT(onTimerAutoSendTimeout()                 ));

    //connect(m_modelTxRxResult,          SIGNAL(rowsInserted(const QModelIndex &, int, int)),
    //        this, SLOT(onModelTxResultRowInserted(const QModelIndex &, int, int)));    //20181214 James remark
    emit toggleAutoSend(true);
}

void MitsubishiWnd::closeEvent(QCloseEvent * event)
{
    Q_UNUSED(event);
    QSettings settings(APP_CONFIG_FILE, QSettings::IniFormat);
    QStringList txQueueData;
    for( int i = 0; i < m_modelTxPktQueue->rowCount(); i ++ )
    {
        txQueueData << m_modelTxPktQueue->item(i, MITSUBISHI_WND_TX_QUEUE_COLUMNS::HEX)->text() + " ," +
                       m_modelTxPktQueue->item(i, MITSUBISHI_WND_TX_QUEUE_COLUMNS::ASCII)->text() + " ," +
                       m_modelTxPktQueue->item(i, MITSUBISHI_WND_TX_QUEUE_COLUMNS::COMMENT)->text();
    }
}

void MitsubishiWnd::addDataToTxRxResultModel(QStringList info)
{
    QStandardItemModel* model = m_modelTxRxResult;

    QList <QStandardItem*> addItems;
    QBrush foregroundBursh(Qt::black);

    for ( int i = 0 ; i < MITSUBISHI_WND_TXRX_RESULT_COLUMNS::COUNT ; i ++ )
    {
        QStandardItem* tempItem = new QStandardItem();
        switch(i)
        {
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::TIMESTAMP:
        {
            QString timeStamp = info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::TIMESTAMP);
            QString status = info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS);
            if( status.contains("RX") == true )
                foregroundBursh.setColor(Qt::blue);
            tempItem->setText(timeStamp);
            break;
        }
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS           :
        {
            QString status = info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS);
            if( status.contains("NOK") == true )
                foregroundBursh.setColor(Qt::red);
            tempItem->setText(status);
            break;
        }
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::MODE           :
        {
            QString status = info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::MODE);
            tempItem->setText(status);
            break;
        }
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA        :
            tempItem->setText(info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA));
            break;
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::CRC        :
            tempItem->setText(info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::CRC));
            break;

        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR             :
            tempItem->setText("[" +info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) + "]");
            break;
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::FUNCTION        :
            tempItem->setText("[" + info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::FUNCTION) + "]");
            break;
        case MITSUBISHI_WND_TXRX_RESULT_COLUMNS::INFO        :
            tempItem->setText(info.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::INFO));
            break;
        }
        addItems << tempItem;
    }
    foreach(QStandardItem* item, addItems)
    {
        item->setEditable(false);
        item->setForeground(foregroundBursh);
    }

    model->appendRow(addItems);
}

void MitsubishiWnd::addDataToTxPktQueueModel(QStringList parsedData)
{
    QStandardItemModel* model = m_modelTxPktQueue;
    QList <QStandardItem*> addItems;
    QBrush foregroundBursh(Qt::black);

    for ( int i = 0 ; i < MITSUBISHI_WND_TX_QUEUE_COLUMNS::COUNT ; i ++ )
    {
        QStandardItem* tempItem = new QStandardItem();

        switch(i)
        {
        case MITSUBISHI_WND_TX_QUEUE_COLUMNS::ENABLE:
        {
            tempItem->setCheckable(true);
            tempItem->setCheckState(Qt::Checked);
            tempItem->setEditable(false);
            break;
        }
        case MITSUBISHI_WND_TX_QUEUE_COLUMNS::HEX        :
            tempItem->setEditable(true);
            tempItem->setText(parsedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA));
            break;

        case MITSUBISHI_WND_TX_QUEUE_COLUMNS::ASCII        :
        {
            tempItem->setEditable(false);

            QByteArray text;
            QByteArray targetText = "";
            text = parsedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA).toLatin1().trimmed();
            text = text.replace(" " , "");
            for (int i =0; i < text.count() ; i = i+2 )
            {
                targetText +=QByteArray::fromHex(text.mid(i, 2));

            }
            tempItem->setText(targetText);
        }
            break;

        case MITSUBISHI_WND_TX_QUEUE_COLUMNS::COMMENT        :
            tempItem->setCheckable(false);
            tempItem->setEditable(true);
            tempItem->setText("\"comment\"");
            break;

        }
        addItems << tempItem;
    }
    foreach(QStandardItem* item, addItems)
    {
        item->setForeground(foregroundBursh);
    }

    model->appendRow(addItems);
}


void MitsubishiWnd::onSendedData(QByteArray data)
{
    QStringList sendedData;
    onParseData_send(sendedData, data);  //
    sendedData[MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS] = "[TX " + sendedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS);
    addDataToTxRxResultModel(sendedData);
    qDebug() << Q_FUNC_INFO << sendedData;
    addTxCount();
    QString sendRawData = sendedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
}

void MitsubishiWnd::onRecvedData(QByteArray data)
{    
    QStringList receivedData;
    onParseData_receive(receivedData, data);
    receivedData[MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS);
    addDataToTxRxResultModel(receivedData);
    qDebug() << Q_FUNC_INFO <<receivedData;
    addRxCount();
    if(m_WgtChanged ==  PLASTIC_MAIN_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            if(m_position==0)
            {
                QString workString = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit workStatus(workString);
            }
            if(m_position==1)
            {
                QString objstring = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit objCount(objstring);
            }
        }
    }
    else if(m_WgtChanged == PROCESS_SELECTION_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            QString processSelection = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
            emit sendProcessSelectionRawData(processSelection);
        }
    }
    else if(m_WgtChanged == INPUT_STATUS_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            QString inputStatus = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
            emit sendInputStatusRawData(inputStatus);
        }
    }
    else if(m_WgtChanged == OUTPUT_STATUS_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            QString outputStatus = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
            emit sendOutputStatusRawData(outputStatus);
        }
    }
    else if(m_WgtChanged == DELAYTIME_SETTING1_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            if(m_position==0)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData1(delay1);
            }
            if(m_position==1)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData2(delay1);
            }
            if(m_position==2)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData3(delay1);
            }
            if(m_position==3)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData4(delay1);
            }
            if(m_position==4)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData5(delay1);
            }
            if(m_position==5)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay1RawData6(delay1);
            }
        }
    }
    else if(m_WgtChanged == DELAYTIME_SETTING2_WGT)
    {
        if(receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02")
        {
            if(m_position==0)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay2RawData1(delay1);
            }
            if(m_position==1)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay2RawData2(delay1);
            }
            if(m_position==2)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay2RawData3(delay1);
            }
            if(m_position==3)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay2RawData4(delay1);
            }
            if(m_position==4)
            {
                QString delay1 = receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                emit sendDelay2RawData5(delay1);
            }
        }
    }
}


void MitsubishiWnd::onRecvedErrorData(QByteArray data)
{    
    qDebug() << Q_FUNC_INFO <<data;
    QStringList receivedData;
    onParseData_receive(receivedData, data);
    receivedData[MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS);
    addDataToTxRxResultModel(receivedData);
    addRxCount();
}

int MitsubishiWnd:: onParseData_send(QStringList &parsedData, QByteArray data)
{    
    qDebug() << Q_FUNC_INFO <<parsedData;
    QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString status = "";
    QString rawData = QString(MitsubishiWnd::toHexString(data));
    QString startCode = "";
    QString commandCode = "";
    QString info = "";
    QString crc = "";
    QString plcMode = "ASCII";
    int exception_code = 0x00;
    if( data.count() >= 4 )
    {
        QString response_start = QString( data.mid(0, 1).toHex() );
        startCode = QString( data.mid(0, 1).toHex() );
        commandCode = QString( data.mid(1, 1).toHex() );
        crc = QString( data.mid(data.count() -2, 2).toHex() );//Must toHex()
        quint8 sum = LSBUS_sum_new(data.mid(0, data.count() - 2));
        QByteArray sum_check = QString::number(sum).toLatin1().toHex();
        //                if( sum_check == crc )
        //                {
        //                    if( response_start == "02" )
        //                    {
        //                        info += QString("[ERROR CODE] ") + data.mid(4, 2) + "  ";
        //                        exception_code = 0xff;
        //                    }
        //                    info += "" + data.mid(0, data.count()) ;
        //                }
        //                else
        //                {
        //                    info = QString("[ERROR SUM] expected %1").arg(sum, 4, 16, QChar('0'));
        //                    exception_code = 0xff;
        //                }
    }
    else
    {
        exception_code = 0xff;
    }
    if( exception_code != 0xff )
    {
        status = "NOK]";
    }
    else
    {
        status = "OK]";
    }

    parsedData << timeStamp << status << plcMode << rawData << crc << startCode << commandCode << info;
    return exception_code;
}

int MitsubishiWnd::onParseData_receive(QStringList &parsedData, QByteArray data)
{
    QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString status = "";
    QString rawData = QString(MitsubishiWnd::toHexString(data));
    QString startCode = "";
    QString commandCode = "";
    QString info = "";
    QString crc = "";
    QString plcMode = "ASCII";
    int exception_code = 0x00;
    if( data.count() >= 4 )
    {
        QString response_start = QString( data.mid(0, 1).toHex() );
        startCode = QString( data.mid(0, 1).toHex() );
        commandCode = QString( data.mid(1, 1).toHex() );
        crc = QString( data.mid(data.count() -2, 2).toHex() );//Must toHex
        quint8 sum = LSBUS_sum_rev(data.mid(0, data.count() - 2));
        QByteArray sum_check =  QByteArray::fromRawData((char*)&sum, 1).toHex().toUpper();
        //                if( sum_check == crc )
        //                {
        //                    if( response_start == "02" )
        //                    {
        //                        info += QString("[ERROR CODE] ") + data.mid(4, 2) + "  ";
        //                        exception_code = 0xff;
        //                    }
        //                    info += "" + data.mid(0, data.count()) ;
        //                }
        //                else
        //                {
        ////                    info = QString("[ERROR SUM] expected %1").arg(sum, 4, 16, QChar('0'));
        //                    exception_code = 0xff;
        //                }
    }
    else
    {
        exception_code = 0xff;
    }



    if( exception_code != 0xff )
    {
        status = "NOK]";
    }
    else
    {
        status = "OK]";
    }

    parsedData << timeStamp << status << plcMode << rawData << crc << startCode << commandCode << info;
    return exception_code;
}

int MitsubishiWnd::onParseData(QStringList &parsedData, QByteArray data, QByteArray minfo)
{
    QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString status = "";
    QString rawData = QString(MitsubishiWnd::toHexString(data));
    QString slaveAddr = "";
    QString function = "";
    QString info = QString(minfo);
    QString crc = "";
    QString commMode = "RTU";

    int exception_code = 0x00;
    if( data.count() >= 4 )
    {
        QString response_start = QString( data.mid(0, 1).toHex() );
        slaveAddr = QString( data.mid(1, 2) );
        function = QString( data.mid(3, 1) );
        crc = QString( data.mid(data.count() -3, 2) );

        quint8 sum = LSBUS_sum(data.mid(0, data.count() - 3));

        if( sum == crc.toInt(NULL, 16) )
        {
            if( response_start == "02" )
            {
                info += QString("[ERROR CODE] ") + data.mid(4, 2) + "  ";
                exception_code = 0xff;
            }
            info += "" + data.mid(0, data.count()) ;
        }
        else
        {
            //            info = QString("[ERROR SUM] expected %1").arg(sum, 4, 16, QChar('0'));
            exception_code = 0xff;
        }
    }
    else
    {
        exception_code = 0xff;
    }
    if( exception_code != 0xff )
    {
        status = "NOK]";
    }
    else
    {
        status = "OK]";
    }

    parsedData << timeStamp << status << commMode << rawData << crc << slaveAddr << function << info;
    return exception_code;
}

void MitsubishiWnd::onCmbComportTextChanged(QString str)
{

}

quint32 MitsubishiWnd::onCmbBaudrateTextChanged(QString str)
{
    QMetaObject::invokeMethod(m_port, "changeBaudrate", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, str.toInt()  ));

    return str.toInt();
}

quint32 MitsubishiWnd::onCmbDataBitsTextChanged(QString str)
{
    QMetaObject::invokeMethod(m_port, "changeDataBits", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, str.toInt()  ));

    return str.toInt();
}
quint32 MitsubishiWnd::onCmbParityTextChanged(QString str)
{
    QSerialPort::Parity parity = QSerialPort::UnknownParity;

    if( str == "none" )
    {
        parity = QSerialPort::NoParity;
    }
    else if ( str == "even" )
    {
        parity = QSerialPort::EvenParity;
    }
    else if ( str == "odd" )
    {
        parity = QSerialPort::OddParity;
    }

    QMetaObject::invokeMethod(m_port, "changeParity", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, parity  ));

    return parity;
}
quint32 MitsubishiWnd::onCmbStopBitsTextChanged(QString str)
{
    QSerialPort::StopBits stopBits = QSerialPort::UnknownStopBits;
    if( str.toInt() == 1 )
        stopBits = QSerialPort::OneStop;
    else if ( str.toInt() == 2)
        stopBits = QSerialPort::TwoStop;

    QMetaObject::invokeMethod(m_port, "changeStopBits", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, stopBits  ));

    return stopBits;
}


void MitsubishiWnd::onLineDecimalChanged()
{
    QString numText = "";
    numText = numText.replace(" ", "");
    int number = numText.toInt();
}

void MitsubishiWnd::onCmbSendCountTextChanged(QString str)
{

}

void MitsubishiWnd::onChkAutoSendToggled(bool checked)
{
    int interval =100;//500 ms
    if( checked == true )
    {
        if( interval == 0 )
        {
            interval = 1;
        }

        connect(m_port, SIGNAL(sgReadyEntered()), m_timerAutoSend, SLOT(start()));
        m_timerAutoSend->setInterval( interval );
        m_timerAutoSend->start();
    }
    else
    {
        disconnect(m_port, SIGNAL(sgReadyEntered()), 0, 0);
        m_timerAutoSend->stop();
    }

}

void MitsubishiWnd::onChkIgnoreAckToggled(bool checked)
{
    if( checked == true )
    {
        m_port->setIgnoreAck(true);
    }
    else
    {
        m_port->setIgnoreAck(false);
    }
}


void MitsubishiWnd::onSetPortTimeOut()
{
    m_port->setResponseTimeout(500 );//设置Port超时时间
}

void MitsubishiWnd::onPortConnected()
{
    emit sgConnected("Connected");
    emit plcConnectStatus(true);

    qDebug() << Q_FUNC_INFO << "Connected";
}
void MitsubishiWnd::onPortDisconnected()
{
    qDebug() << Q_FUNC_INFO << "DisConnected";
    m_timerAutoSend->stop();
    emit sgDisconnected( m_port->errorString());
    emit plcConnectStatus(false);
    onTryConnectPort();//When find com port is disconnected, than always try connected;
}
void MitsubishiWnd::onPortResponseTimeout()
{
    QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString status = "[RX NOK]";
    QString rawData = "";
    QString slaveAddr = "";
    QString function = "";
    QString info = QString("[ERROR TIMEOUT INTERVAL] %1 msec").arg(QString("%1").arg(m_port->responseTimeout()));
    QString crc = "";
    QStringList rowItems;
    QString commMode = "";
    rowItems << timeStamp << status << commMode << rawData << crc << slaveAddr << function << info ;
    addDataToTxRxResultModel(rowItems);
    addErrorCount();
}


void MitsubishiWnd::onTryConnectPort()
{
    QMetaObject::invokeMethod(m_port, "tryConnect", Qt::QueuedConnection ,
                              Q_ARG(QString, mComPortSetting.cmbComPort),
                              Q_ARG(quint32, onCmbBaudrateTextChanged(mComPortSetting.cmbBaudrate) ),
                              Q_ARG(quint32, onCmbDataBitsTextChanged(mComPortSetting.cmbDataBits) ),
                              Q_ARG(quint32, onCmbParityTextChanged(mComPortSetting.cmbParity) ),
                              Q_ARG(quint32, onCmbStopBitsTextChanged(mComPortSetting.cmbStopBits) )
                              );

}
void MitsubishiWnd::onCloseConnetPort()
{
    QMetaObject::invokeMethod(m_port, "tryDisconnect", Qt::QueuedConnection);
}

void MitsubishiWnd::onBtnScreenClearClicked()
{
    resetRxCount();
    resetTxCount();
    resetErrorCount();
    removeModelTxRxResult();
}
void MitsubishiWnd::removeModelTxRxResult()
{
    int removeCount = m_modelTxRxResult->rowCount();
    for ( int i = 0; i < removeCount; i++ )
    {
        m_modelTxRxResult->removeRow(0);
    }
}


void MitsubishiWnd::onErrorCountChanged()
{
}

void MitsubishiWnd::initPowerOn()
{   
    onSendWriteProcessStatusCmd("02","30","1028","04","03","ASCII");
}

void MitsubishiWnd::onSendWriteProcessStatusCmd(QString mStartCode, QString mCommandCode, QString mStartAddr, QString mNumOfRegister, QString mEndCode, QString mplcMode)
{
    QByteArray startCode = mStartCode.simplified().mid(0, 2).toLatin1();//02
    QByteArray commandCode =mCommandCode.simplified().mid(0, 2).toLatin1();//30
    QByteArray startAddr = mStartAddr.simplified().mid(0, 4).toLatin1();// 31 30 32 38  (1028)
    QByteArray numOfRegister = mNumOfRegister.simplified().mid(0,2).toLatin1();//30 34 (04)
    QByteArray endCode = mEndCode.simplified().mid(0, 2).toLatin1();//03
    QByteArray sendData = "";
    if(mplcMode.contains("ASCII"))
    {
        sendData = makeMisubishiFxFrame_OfWrite(startCode, commandCode, startAddr, numOfRegister,endCode);
    }

    //    qDebug() << Q_FUNC_INFO << "commMode" << commMode << "slave" << slaveAddr.toHex() << "function" << commandCode.toHex() <<
    //                "startAddr" << startAddr.toHex() << "number of register" << numOfRegister.toHex() << "byte Count" << byteCount.toHex() << "sendData" << sendData.toHex();
    QStringList parsedData;
    onParseData_send(parsedData, sendData);//含CRC校验

    qDebug() << Q_FUNC_INFO << "parsedData:" <<parsedData;
    emit sendWriteList(parsedData);
}

void MitsubishiWnd::onSendInitWriteCmd(QString mStartCode, QString mCommandCode, QString mStartAddr, QString mNumOfRegister,QString mRriteData,QString mEndCode, QString mplcMode)
{
    QByteArray startCode = mStartCode.simplified().mid(0, 2).toLatin1();//02
    QByteArray commandCode =mCommandCode.simplified().mid(0, 2).toLatin1();//30
    QByteArray startAddr = mStartAddr.simplified().mid(0, 4).toLatin1();// 31 30 32 38  (1028)
    QByteArray numOfRegister = mNumOfRegister.simplified().mid(0,2).toLatin1();//30 34 (04)
    QByteArray writeData = mRriteData.simplified().mid(0,4).toLatin1();
    QByteArray endCode = mEndCode.simplified().mid(0, 2).toLatin1();//03
    QByteArray sendData = "";
    if(mplcMode.contains("ASCII"))
    {
        sendData = makeMisubishiFxWriteFrame(startCode, commandCode, startAddr, numOfRegister,writeData,endCode);
    }
    QStringList parsedData;
    onParseData_send(parsedData, sendData);//含CRC校验
    qDebug() << Q_FUNC_INFO << parsedData;
    emit sendWriteList(parsedData);
}

void MitsubishiWnd::onSendCmd(QString mStartCode,QString mCommandCode,QString mStartAddr,QString mNumOfRegister,QString mEndCode,QString mplcMode)
{
    QByteArray startCode = mStartCode.simplified().mid(0, 2).toLatin1();//02
    QByteArray commandCode =mCommandCode.simplified().mid(0, 2).toLatin1();//30
    QByteArray startAddr = mStartAddr.simplified().mid(0, 4).toLatin1();// 31 30 32 38  (1028)
    QByteArray numOfRegister = mNumOfRegister.simplified().mid(0,2).toLatin1();//30 34 (04)
    QByteArray endCode = mEndCode.simplified().mid(0, 2).toLatin1();//03
    QByteArray sendData = "";
    if(mplcMode.contains("ASCII"))
    {
        sendData = makeMisubishiFxFrame(startCode, commandCode, startAddr, numOfRegister,endCode);
    }
    //    qDebug() << Q_FUNC_INFO << "commMode" << commMode << "slave" << slaveAddr.toHex() << "function" << commandCode.toHex() <<
    //                "startAddr" << startAddr.toHex() << "number of register" << numOfRegister.toHex() << "byte Count" << byteCount.toHex() << "sendData" << sendData.toHex();
    QStringList parsedData;
    onParseData_send(parsedData, sendData);//含CRC校验
    addDataToTxPktQueueModel(parsedData);
}

void MitsubishiWnd::btnTxQueueFileOpenClicked()
{
    qDebug() << Q_FUNC_INFO;
}

void MitsubishiWnd::btnTxqueueFileSaveClicked()
{
    qDebug() << Q_FUNC_INFO;

}

void MitsubishiWnd::onModelTxPktQueueDataChanged(QModelIndex topLeft, QModelIndex bottomRight )
{
    int row = topLeft.row();
    int col = topLeft.column();

    if( col == MITSUBISHI_WND_TX_QUEUE_COLUMNS::HEX )
    {
        QString str = m_modelTxPktQueue->item(row, col)->text();
        QString asciiStr = "";
        str = str.trimmed();
        str = str.replace(" ", "");
        for(int i = 0; i < str.count()/2 ; i++ )
        {
            asciiStr += QByteArray::fromHex(str.mid(i*2, 2).toLatin1());
        }
        m_modelTxPktQueue->setItem(row, col+1, new QStandardItem(asciiStr));
    }
}

void MitsubishiWnd::onTimerAutoSendTimeout()//定时发送
{
    onReadyEntered();
}

void MitsubishiWnd::onModelTxResultRowInserted(const QModelIndex & parent, int first, int last)
{
    //    qDebug() << Q_FUNC_INFO << first << last << m_modelTxRxResult->rowCount();

    if( m_txRxResultMaxRow *2  < m_modelTxRxResult->rowCount() )
    {

        QString saveFilePath = QDir::currentPath();
        QString filePath = saveFilePath + + "/" + QDateTime::currentDateTime().toString("MM-dd_HH-mm") + ".csv";

        //        qDebug() << Q_FUNC_INFO << filePath;
        QFile file;
        file.setFileName(filePath);

        QIODevice::OpenModeFlag openMode;
        openMode = QIODevice::WriteOnly;

        if( file.open(openMode) == true )
        {
            file.seek(file.size() );
            QString rowData = "";

            for(int i = 0 ; i < m_viewTxRxResult->horizontalHeader()->count() ; i ++ )
            {
                if( i  != m_viewTxRxResult->horizontalHeader()->count() - 1)
                    rowData += m_modelTxRxResult->horizontalHeaderItem(i)->text() + ",";
                else
                    rowData += m_modelTxRxResult->horizontalHeaderItem(i)->text() + "\n";

            }

            file.write(rowData.toLatin1());
            rowData = "";

            for(int i = 0 ; i < m_txRxResultMaxRow; i ++ )
            {

                QList <QStandardItem*> items;
                items = m_modelTxRxResult->takeRow(0);
                rowData = "";
                rowData += " " + items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::TIMESTAMP)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::STATUS)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::MODE)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::RAWDATA)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::CRC)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::FUNCTION)->text() + ",";
                rowData += items.at(MITSUBISHI_WND_TXRX_RESULT_COLUMNS::INFO)->text() + "\n";

                file.write(rowData.toLatin1());

                foreach(QStandardItem* item, items)
                {
                    if( item != 0 )
                        delete item;
                }
            }
            file.flush();
        }
        else
        {
            qWarning() <<  Q_FUNC_INFO << "file save fail" << file.errorString();

        }
        file.close();

    }
}

void MitsubishiWnd::onViewTxQueueDataSelectionCurrentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
}


void MitsubishiWnd::sendModelTxPktQueue(int index )//向从设备发送数据
{
    if( index >= m_modelTxPktQueue->rowCount() )
    {
        //        qDebug() << Q_FUNC_INFO << "index overflow";
        return;
    }

    QByteArray sendData;

    //    QString arr = "01 03 00 00 00 0F 05 CE";
    sendData = QByteArray::fromHex( m_modelTxPktQueue->item(index, MITSUBISHI_WND_TX_QUEUE_COLUMNS::HEX )->text().toLatin1());
    //    qDebug() << Q_FUNC_INFO << sendData.toHex();
    qDebug() << Q_FUNC_INFO << sendData.toHex();
    QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                              Q_ARG(QByteArray, sendData ));
}

void MitsubishiWnd::onReadyEntered()
{
    //    qDebug() << Q_FUNC_INFO;
    static int index = 0;

    if( m_modelTxPktQueue->rowCount() == 0)
    {
        return;
    }

    for(int count = 0; count < m_modelTxPktQueue->rowCount(); count ++)
    {
        int position = (index + count)  % m_modelTxPktQueue->rowCount();
        if( m_modelTxPktQueue->item(position, MITSUBISHI_WND_TX_QUEUE_COLUMNS::ENABLE )->checkState() == Qt::Checked )
        {
            m_timerAutoSend->stop();
            sendModelTxPktQueue(position);
            m_position = position;
            index = (position+1) % m_modelTxPktQueue->rowCount();
            break;
        }
        else
        {
            m_timerAutoSend->start();
        }
    }
}

void MitsubishiWnd::onReceiveWriteList(QStringList parsedData)
{
    {
        QByteArray sendData;
        QString rawData = "";
        for(int i = 0; i < parsedData.count(); i++)
        {
            if(i==3)
            {
                rawData = parsedData.at(3);
            }
        }
        sendData = QByteArray::fromHex( rawData.toLatin1() );
        qDebug() << Q_FUNC_INFO << sendData.toHex();
        QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                  Q_ARG(QByteArray, sendData ));
    }

}

void MitsubishiWnd::getTransforWgt(WgtChanged wgt)
{
    m_WgtChanged = wgt;
    switch (wgt) {
    case PLASTIC_MAIN_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        onSendCmd("02","30","1000","0E","03","ASCII");//读工作参数
        onSendCmd("02","30","117C","04","03","ASCII");//读取工件计数值
        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }
        break;
    case MAIN_MENU_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
    }
        break;
    case PROCESS_SELECTION_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
        onSendCmd("02","30","0132","02","03","ASCII");
        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }

        break;
    case INPUT_STATUS_WGT://
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
        onSendCmd("02","30","0082","02","03","ASCII");
        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }

        break;
    case OUTPUT_STATUS_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
        onSendCmd("02","30","00A0","02","03","ASCII");
        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }
        break;

    case DELAYTIME_SETTING1_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
        onSendCmd("02","30","1104","02","03","ASCII");//di ya pai qi
        onSendCmd("02","30","110E","02","03","ASCII");//gao ya pai qi
        onSendCmd("02","30","1118","02","03","ASCII");//di ya bao ya
        onSendCmd("02","30","1122","02","03","ASCII");//xie ya yanshi
        onSendCmd("02","30","112C","02","03","ASCII");//di ya paiqi yanshi
        onSendCmd("02","30","1136","02","03","ASCII");//gao ya baoya yanshi

        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }

        break;

    case DELAYTIME_SETTING2_WGT:
    {
        int removeCount = m_modelTxPktQueue->rowCount();
        for(int i = 0; i < removeCount; i++)
        {
            m_modelTxPktQueue->removeRow(0);
        }
        emit workStatus("");
        emit objCount("");
        onSendCmd("02","30","1140","02","03","ASCII");//泄压延时2
        onSendCmd("02","30","114A","02","03","ASCII");//高压排气延时
        onSendCmd("02","30","1154","0C","03","ASCII");//成型保压延时
        onSendCmd("02","30","1168","02","03","ASCII");//顶出延时时间
        onSendCmd("02","30","115E","04","03","ASCII");//泄压延时
        if(m_timerAutoSend)
        {
            if(!m_timerAutoSend->isActive())
                m_timerAutoSend->start();
        }
    }
        break;
    default:
        break;
    }
}

void MitsubishiWnd::writeLowpressStatus(bool flag)
{
    toggleAutoSendFun(false);
    if(flag)
    {
        onSendWriteProcessStatusCmd("02","37","9209","","03","ASCII");//写有低压排气
    }
    else
    {
        onSendWriteProcessStatusCmd("02","38","9209","","03","ASCII");//写无低压排气
    }
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeAftercompactionStatus(bool flag)
{
    toggleAutoSendFun(false);
    if(flag)
    {
        onSendWriteProcessStatusCmd("02","37","9609","","03","ASCII");//写有补压
    }
    else
    {
        onSendWriteProcessStatusCmd("02","38","9609","","03","ASCII");//写无补压
    }
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeChouXinGangStatus(bool flag)
{
    toggleAutoSendFun(false);
    if(flag)
    {
        onSendWriteProcessStatusCmd("02","37","9009","","03","ASCII");//写 Auto Chouxingang
    }
    else
    {
        onSendWriteProcessStatusCmd("02","38","9009","","03","ASCII");//写 Mannal chouxingang
    }
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeMotorStatus(bool flag)
{
    toggleAutoSendFun(false);
    if(flag)
    {
        onSendWriteProcessStatusCmd("02","37","9809","","03","ASCII");//写 motor stop
    }
    else
    {
        onSendWriteProcessStatusCmd("02","38","9809","","03","ASCII");//写 motor donnot stop
    }
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeGaoYaPaiQiStatus(bool flag)
{
    toggleAutoSendFun(false);
    if(flag)
    {
        onSendWriteProcessStatusCmd("02","37","9409","","03","ASCII");//写 have 高压排气
    }
    else
    {
        onSendWriteProcessStatusCmd("02","38","9409","","03","ASCII");//写 donnot have 高压排气
    }
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeLowPressureCount(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1104", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeHighPressureCount(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "110E", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeLowProtectDelaytime(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1118", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeReliefPressureDelaytime(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1122", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeLowPressurePaiqiDelaytime(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "112C", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeHighPressureBaoyaDelaytime(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1136", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeReliefPressureDelaytime2_2(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1140", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeHighPressurePaiqiDelaytime_2(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "114A", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeMoldingBaoyaDelaytime_2(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1154", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeTopoutDelaytime_2(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "1168", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeReliefPressureDelaytime_2(QString value, QString bytesCount)
{
    toggleAutoSendFun(false);
    onSendInitWriteCmd("02", "31", "115E", bytesCount, value, "03", "ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::writeClearCount()
{
    //TODO 20180719
    toggleAutoSendFun(false);
    onSendWriteProcessStatusCmd("02","37","8F09","","03","ASCII");//计数清零
    /*clear CMD ----zhanglong*/
    onSendWriteProcessStatusCmd("02","38","8F09","","03","ASCII");
    toggleAutoSendFun(true);
}

void MitsubishiWnd::toggleAutoSendFun(bool check)//need todo
{
    emit toggleAutoSend(check);
}

int MitsubishiWnd::getWarnValue()
{
    return m_warnValue;
}

void MitsubishiWnd::setWarnValue(int value)
{
    m_warnValue = value;
}

void MitsubishiWnd::setAmmeterValue(float)
{

}

QByteArray MitsubishiWnd::toHexString(QByteArray buf)
{
    QByteArray temp = "";
    for(int i =0; i < buf.count() ; i ++ )
    {
        if( i == buf.count() -1 )
            temp += buf.mid(i, 1).toHex();
        else
            temp += buf.mid(i, 1).toHex() + " ";
    }
    return temp;
}
bool MitsubishiWnd::check_ModbusRTU_CRC16(QByteArray buf, quint16 &result)
{
    if( buf.size() >= 4 )
    {
        QByteArray srcCrc = buf.mid(buf.size()-2, 2);
        QByteArray dstCrc = "";
        if( srcCrc == dstCrc )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    result = 0xffff;
    return false;
}

quint8 MitsubishiWnd::LSBUS_sum (QByteArray buf)
{
    quint8 sum = 0x00;
    for ( int i = 1 ; i < buf.count() ; i ++ )
    {
        sum += buf.at(i);
    }
    return sum;
}

quint8 MitsubishiWnd::LSBUS_sum_new(QByteArray buf)
{
    quint8 sum = 0x00;
    for ( int i = 1 ; i < buf.count() ; i ++ )
    {
        sum += QByteArray(1, buf.at(i)).toHex().toInt(Q_NULLPTR,16);
    }
    sum = QByteArray(1, sum).toHex().toInt();
    return sum;
}

quint8 MitsubishiWnd::LSBUS_sum_rev(QByteArray buf)
{
    quint8 sum = 0x00;
    for ( int i = 1 ; i < buf.count() ; i ++ )
    {
        sum += QByteArray(1, buf.at(i)).toHex().toInt(Q_NULLPTR,16);
    }
    return sum;
}

QByteArray MitsubishiWnd::makeMisubishiFxFrame(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr,QByteArray numOfRegister,QByteArray endCode)
{
    QByteArray modbusPDU = "";
    if(CommandCode == "30")
    {
        modbusPDU += startAddr + numOfRegister;
    }

    QByteArray frame ="";
    QDataStream ds(&frame, QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::LittleEndian);
    ds << qint8(0x02);
    ds << qint8(0x30);
    // 如果QByteArray有0x00数据，它不会检查size()
    ds.writeRawData(modbusPDU.constData(), modbusPDU.size());
    ds << qint8(0x03);
    quint8 sum = LSBUS_sum(frame);
    ds.writeRawData( QByteArray::number(sum, 16).toUpper().constData(), 2 );
    return frame;
}

QByteArray MitsubishiWnd::makeMisubishiFxFrame_OfWrite(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr, QByteArray numOfRegister, QByteArray endCode)
{
    QByteArray modbusPDU = "";
    if(CommandCode == "37" || CommandCode == "38")
    {
        modbusPDU += startAddr + numOfRegister;
    }
    QByteArray frame ="";
    QDataStream ds(&frame, QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::LittleEndian);
    ds << qint8(0x02);
    if(CommandCode=="37")
        ds << qint8(0x37);
    else if(CommandCode=="38")
        ds << qint8(0x38);
    // 如果QByteArray有0x00数据，它不会检查size()
    ds.writeRawData(modbusPDU.constData(), modbusPDU.size());
    ds << qint8(0x03);
    quint8 sum = LSBUS_sum(frame);
    ds.writeRawData( QByteArray(1, sum).toHex().toUpper(), 2 );//solve the E to 0E than convert to the ASCII : 30 45 --- like this
    return frame;
}

QByteArray MitsubishiWnd::makeMisubishiFxWriteFrame(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr, QByteArray numOfRegister,QByteArray writeData ,QByteArray endCode)
{
    QByteArray modbusPDU = "";
    if(CommandCode == "31")
    {
        modbusPDU += startAddr + numOfRegister +writeData;
    }

    QByteArray frame ="";
    QDataStream ds(&frame, QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::LittleEndian);
    ds << qint8(0x02);
    ds << qint8(0x31);
    // 如果QByteArray有0x00数据，它不会检查size()
    ds.writeRawData(modbusPDU.constData(), modbusPDU.size());
    ds << qint8(0x03);
    quint8 sum = LSBUS_sum(frame);
    ds.writeRawData( QByteArray::number(sum, 16).toUpper().constData(), 2 );
    return frame;
}
